package com.cskayan.javase.object._6clone;

/**
 * 深度克隆练习：请完成类FirstLevel的深度克隆。
 * 现在有三个类 FirstLevel 、SecondLevel 、ThirdLevel
 *      分析:
 *          1.先对FirstLevel类做深度克隆,需要克隆一次SecondLevel对象
 *          2.然后对SecondLevel类做深度克隆,需要克隆一次ThirdLevel对象
 *          3.ThirdLevel类不需要再做深度克隆
 *
 * @since 14:41
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo3 {
    public static void main(String[] args) throws CloneNotSupportedException {
        /*FirstLevel first = new FirstLevel(1, 2, new SecondLevel(10, 20, new ThirdLevel(100, 200)));

        FirstLevel cloneFirst = first.clone();
        System.out.println(first.second);
        System.out.println(cloneFirst.second);
        System.out.println("----------------------");
        System.out.println(first.second.third);
        System.out.println(cloneFirst.second.third);
*/

        FirstLevel first = new FirstLevel(1, 2, new SecondLevel(10, 20, new ThirdLevel(100, 200, "张三")));
        FirstLevel cloneFirst = first.clone();
        first.second.third.name = "李四";
        System.out.println(cloneFirst.second.third.name);
    }
}

class FirstLevel implements Cloneable{
    int firstIntValue;
    double firstDoubleValue;
    SecondLevel second;

    public FirstLevel(int firstIntValue, double firstDoubleValue, SecondLevel second) {
        this.firstIntValue = firstIntValue;
        this.firstDoubleValue = firstDoubleValue;
        this.second = second;
    }
    // 对FirstLevel类做深度克隆
    @Override
    protected FirstLevel clone() throws CloneNotSupportedException {
        // 1.深度克隆是在浅克隆的基础上完成的.
        FirstLevel cloneFirst = (FirstLevel) super.clone();
        // 2.将引用second指向的SecondLevel对象,克隆一份
        SecondLevel cloneSecond = second.clone();

        // 3.将拷贝对象中的拷贝引用second指向克隆的SecondLevel对象
        cloneFirst.second = cloneSecond;
        return cloneFirst;
    }
}

class SecondLevel implements Cloneable{
    int secondIntValue;
    double secondDoubleValue;
    ThirdLevel third;

    public SecondLevel(int secondIntValue, double secondDoubleValue, ThirdLevel third) {
        this.secondIntValue = secondIntValue;
        this.secondDoubleValue = secondDoubleValue;
        this.third = third;
    }

    // 对SecondLevel类做深度克隆
    @Override
    protected SecondLevel clone() throws CloneNotSupportedException {
        SecondLevel cloneSecond = (SecondLevel) super.clone();
        ThirdLevel cloneThird = third.clone();
        cloneSecond.third = cloneThird;
        return cloneSecond;
    }
}

class ThirdLevel implements Cloneable{
    int thirdIntValue;
    double thirdDoubleValue;

    /*
        String类是常见的引用数据类型
        但是它不需要做深度克隆
        不用担心浅拷贝的问题
     */
    String name;

    public ThirdLevel(int thirdIntValue, double thirdDoubleValue) {
        this.thirdIntValue = thirdIntValue;
        this.thirdDoubleValue = thirdDoubleValue;
    }

    public ThirdLevel(int thirdIntValue, double thirdDoubleValue, String name) {
        this.thirdIntValue = thirdIntValue;
        this.thirdDoubleValue = thirdDoubleValue;
        this.name = name;
    }

    // 它不需要深度克隆了
    @Override
    protected ThirdLevel clone() throws CloneNotSupportedException {
        return (ThirdLevel) super.clone();
    }
}